<template>
  <ContentWrap>
    <!-- 搜索工作栏 -->
    <el-form
      class="-mb-15px"
      :model="queryParams"
      ref="queryFormRef"
      :inline="true"
      label-width="68px"
    >
      <el-form-item label="软件名称" prop="name">
        <el-input
          v-model="queryParams.name"
          placeholder="请输入软件名称"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px"
        />
      </el-form-item>
      <el-form-item label="软件版本" prop="version">
        <el-input
          v-model="queryParams.version"
          placeholder="请输入软件版本"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px"
        />
      </el-form-item>
      <el-form-item label="开发商" prop="developer">
        <el-input
          v-model="queryParams.developer"
          placeholder="请输入开发商"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px"
        />
      </el-form-item>
      <el-form-item label="软件类别" prop="category">
        <el-input
          v-model="queryParams.category"
          placeholder="请输入软件类别"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px"
        />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px">
          <el-option
            v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
        <el-button
          type="primary"
          plain
          @click="openForm('create')"
          v-hasPermi="['compo:software-info:create']"
        >
          <Icon icon="ep:plus" class="mr-5px" /> 新增
        </el-button>
        <el-button
          type="success"
          plain
          @click="handleExport"
          :loading="exportLoading"
          v-hasPermi="['compo:software-info:export']"
        >
          <Icon icon="ep:download" class="mr-5px" /> 导出
        </el-button>
      </el-form-item>
    </el-form>
  </ContentWrap>

  <!-- 列表 -->
  <ContentWrap>
    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
      <el-table-column label="软件ID" align="center" prop="id" />
      <el-table-column label="软件名称" align="center" prop="name" />
      <el-table-column label="软件版本" align="center" prop="version" />
      <el-table-column label="软件描述" align="center" prop="description" />
      <el-table-column label="开发商" align="center" prop="developer" />
      <el-table-column label="软件类别" align="center" prop="category" />
      <el-table-column label="状态" align="center" prop="status">
        <template #default="scope">
          <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
        </template>
      </el-table-column>
      <el-table-column label="文件列表" align="center" min-width="150px">
        <template #default="scope">
          <el-button
            link
            type="primary"
            @click="openFileDialog(scope.row)"
            v-if="scope.row.fileList && scope.row.fileList.length > 0"
          >
            查看文件 ({{ scope.row.fileList ? scope.row.fileList.length : 0 }})
          </el-button>
          <span v-else>无文件</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" min-width="120px">
        <template #default="scope">
          <el-button
            link
            type="primary"
            @click="openForm('update', scope.row.id)"
            v-hasPermi="['compo:software-info:update']"
          >
            编辑
          </el-button>
          <el-button
            link
            type="danger"
            @click="handleDelete(scope.row.id)"
            v-hasPermi="['compo:software-info:delete']"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <Pagination
      :total="total"
      v-model:page="queryParams.pageNo"
      v-model:limit="queryParams.pageSize"
      @pagination="getList"
    />
  </ContentWrap>

  <!-- 表单弹窗：添加/修改 -->
  <SoftwareInfoForm ref="formRef" @success="getList" />

  <!-- 文件预览弹窗 -->
  <el-dialog v-model="fileDialogVisible" title="文件列表" width="800px" fullscreen>
    <el-tabs v-model="activeFileTab">
      <el-tab-pane label="文件预览" name="preview">
        <el-table :data="currentFiles" stripe border>
          <el-table-column label="文件类型" prop="fileType" min-width="120">
            <template #default="scope">
              <dict-tag :type="DICT_TYPE.COMPO_SOFTWARE_FILE_TYPE" :value="scope.row.fileType" />
            </template>
          </el-table-column>
          <el-table-column label="文件名称" prop="fileName" min-width="180" />
          <el-table-column label="文件大小" min-width="100">
            <template #default="scope">
              {{ formatFileSize(scope.row.fileSize) }}
            </template>
          </el-table-column>
          <el-table-column
            label="文件描述"
            prop="description"
            min-width="200"
            show-overflow-tooltip
          />
          <el-table-column label="操作" width="150" align="center">
            <template #default="scope">
              <el-button link type="primary" @click="previewFile(scope.row)"> 预览 </el-button>
              <el-button link type="success" @click="downloadHistoryFile(scope.row)"> 下载 </el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane label="变更记录" name="history">
        <div class="filter-container mb-15px">
          <el-input
            v-model="historyQuery.fileName"
            placeholder="文件名称"
            clearable
            class="filter-item w-200px mr-10px"
            @keyup.enter="handleHistorySearch"
          />
          <el-select
            v-model="historyQuery.fileType"
            placeholder="文件类型"
            clearable
            class="filter-item w-200px mr-10px"
          >
            <el-option
              v-for="dict in getStrDictOptions(DICT_TYPE.COMPO_SOFTWARE_FILE_TYPE)"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
          <el-button type="primary" @click="handleHistorySearch">
            <Icon icon="ep:search" class="mr-5px" /> 搜索
          </el-button>
          <el-button @click="resetHistoryQuery">
            <Icon icon="ep:refresh" class="mr-5px" /> 重置
          </el-button>
        </div>
        
        <el-empty
          v-if="!fileHistoryLoading && (!fileHistory || fileHistory.length === 0)"
          description="暂无变更记录"
        />
        <el-table v-else v-loading="fileHistoryLoading" :data="fileHistory" stripe border>
          <el-table-column label="版本" prop="version" width="100" />
          <el-table-column label="文件名称" prop="fileName" min-width="180" />
          <el-table-column label="文件类型" width="120">
            <template #default="scope">
              <dict-tag :type="DICT_TYPE.COMPO_SOFTWARE_FILE_TYPE" :value="scope.row.fileType" />
            </template>
          </el-table-column>
          <el-table-column label="变更时间" width="160">
            <template #default="scope">
              {{ formatDateTime(scope.row.updateTime) }}
            </template>
          </el-table-column>
          <el-table-column label="变更人" prop="updaterName" width="120" />
          <el-table-column
            label="变更描述"
            prop="description"
            min-width="200"
            show-overflow-tooltip
          />
          <el-table-column label="操作" width="150" align="center">
            <template #default="scope">
              <el-button link type="primary" @click="downloadHistoryFile(scope.row)">
                下载
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <Pagination
          v-if="fileHistory.length > 0"
          :total="historyTotal"
          v-model:page="historyQuery.pageNo"
          v-model:limit="historyQuery.pageSize"
          @pagination="loadFileHistory"
        />
      </el-tab-pane>
    </el-tabs>
  </el-dialog>

  <!-- 文件预览弹窗 -->
  <el-dialog v-model="previewDialogVisible" title="文件预览" width="90%" fullscreen>
    <div class="file-preview-container">
      <!-- 图片预览 -->
      <div v-if="fileType === 'image'" class="image-preview">
        <img :src="previewUrl" alt="图片预览" class="preview-image" />
      </div>
      
      <!-- PDF预览 -->
      <iframe v-else-if="fileType === 'pdf'" :src="previewUrl" class="file-preview-frame"></iframe>
      
      <!-- 文本预览 -->
      <div v-else-if="fileType === 'text'" class="text-preview">
        <pre v-if="textContent" class="text-content">{{ textContent }}</pre>
        <div v-else class="loading-text">加载文本内容中...</div>
      </div>
      
      <!-- Office文档预览 -->
      <div v-else-if="fileType === 'office'" class="office-preview">
        <iframe :src="officePreviewUrl" class="file-preview-frame"></iframe>
      </div>
      
      <!-- 不支持预览的文件类型 -->
      <el-empty v-else description="该文件类型不支持预览，请下载后查看" />
    </div>
    <template #footer>
      <el-button @click="previewDialogVisible = false">关闭</el-button>
      <el-button type="primary" @click="downloadCurrentFile">下载</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import download from '@/utils/download'
import { SoftwareInfoApi, SoftwareInfoVO } from '@/api/compo/softwareInfo'
import { SoftwarFileVersionApi } from '@/api/compo/softwarFileVersion'
import { SoftwareInfoForm } from './components'
import dayjs from 'dayjs'
import { ElLoading } from 'element-plus'

/** 软件信息 列表 */
defineOptions({ name: 'SoftwareInfo' })

const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化

const loading = ref(true) // 列表的加载中
const list = ref<SoftwareInfoVO[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  name: undefined,
  version: undefined,
  developer: undefined,
  category: undefined,
  status: undefined
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中

// 文件对话框相关
const fileDialogVisible = ref(false)
const activeFileTab = ref('preview')
const currentSoftware = ref<SoftwareInfoVO>()
const currentFiles = ref<any[]>([])
const fileHistory = ref<any[]>([])
const fileHistoryLoading = ref(false)
const historyTotal = ref(0)
const historyQuery = reactive({
  softwareId: undefined as number | undefined,
  fileType: undefined as string | undefined,
  fileName: undefined as string | undefined,
  pageNo: 1,
  pageSize: 10
})
const previewDialogVisible = ref(false)
const previewUrl = ref('')
const currentPreviewFile = ref<any>(null)
const fileType = ref<'image' | 'pdf' | 'text' | 'office' | 'other'>('other')
const textContent = ref<string>('')
const officePreviewUrl = ref('')

/** 查询列表 */
const getList = async () => {
  loading.value = true
  try {
    const data = await SoftwareInfoApi.getSoftwareInfoPage(queryParams)
    list.value = data.list
    total.value = data.total
  } finally {
    loading.value = false
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
  formRef.value.open(type, id)
}

/** 删除按钮操作 */
const handleDelete = async (id: number) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await SoftwareInfoApi.deleteSoftwareInfo(id)
    message.success(t('common.delSuccess'))
    // 刷新列表
    await getList()
  } catch {}
}

/** 导出按钮操作 */
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const data = await SoftwareInfoApi.exportSoftwareInfo(queryParams)
    download.excel(data, '软件信息.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}

/** 打开文件对话框 */
const openFileDialog = (row: SoftwareInfoVO) => {
  currentSoftware.value = row
  currentFiles.value = row.fileList || []
  fileDialogVisible.value = true
  activeFileTab.value = 'preview'
  
  // 重置历史查询条件
  resetHistoryQuery()
  historyQuery.softwareId = row.id

  // 如果切换到历史记录标签页，加载历史数据
  watch(activeFileTab, (tab) => {
    if (tab === 'history') {
      loadFileHistory()
    }
  })
}

/** 搜索历史记录 */
const handleHistorySearch = () => {
  historyQuery.pageNo = 1
  loadFileHistory()
}

/** 重置历史查询条件 */
const resetHistoryQuery = () => {
  historyQuery.fileType = undefined
  historyQuery.fileName = undefined
  historyQuery.pageNo = 1
  historyQuery.pageSize = 10
}

/** 加载文件历史记录 */
const loadFileHistory = async () => {
  if (!currentSoftware.value || !historyQuery.softwareId) return

  fileHistoryLoading.value = true
  try {
    // 调用获取软件所有文件版本历史的API
    // 确保softwareId是一个数字
    const params = {
      ...historyQuery,
      softwareId: Number(historyQuery.softwareId) // 确保是数字类型
    }
    
    const res = await SoftwarFileVersionApi.getSoftwarFileVersionPage(params)
    fileHistory.value = res.list || []
    historyTotal.value = res.total || 0
    
    if (fileHistory.value.length === 0 && historyQuery.pageNo === 1) {
      // 没有历史记录时给出提示
      message.info('暂无符合条件的版本历史记录')
    }
  } catch (error) {
    console.error('获取文件历史记录失败', error)
    message.error('获取文件历史记录失败')
    fileHistory.value = []
    historyTotal.value = 0
  } finally {
    fileHistoryLoading.value = false
  }
}

/** 格式化文件大小 */
const formatFileSize = (size: number) => {
  if (!size) return '0 B'

  const units = ['B', 'KB', 'MB', 'GB', 'TB']
  let i = 0
  while (size >= 1024 && i < units.length - 1) {
    size /= 1024
    i++
  }

  return `${size.toFixed(2)} ${units[i]}`
}

/** 格式化日期时间 */
const formatDateTime = (timestamp: number | string | Date) => {
  if (!timestamp) {
    return '-'
  }
  
  // 如果是毫秒时间戳，直接格式化
  try {
    return dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss')
  } catch (error) {
    console.error('时间格式化错误', error)
    return '-'
  }
}

/** 预览文件 */
const previewFile = async (file: any) => {
  currentPreviewFile.value = file
  
  // 根据文件扩展名确定文件类型
  const fileExt = file.fileName.split('.').pop()?.toLowerCase() || ''
  const baseUrl = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL
  
  // 判断文件路径是否为完整URL
  let filePath = file.filePath
  // 检查是否为外部URL（以http://或https://开头）
  if (filePath.startsWith('http://') || filePath.startsWith('https://')) {
    // 如果是完整URL，直接使用
    previewUrl.value = filePath
  } else {
    // 如果是相对路径，拼接baseUrl
    previewUrl.value = baseUrl + filePath
  }
  
  // 根据文件类型处理预览
  if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(fileExt)) {
    // 图片文件直接使用img标签预览
    fileType.value = 'image'
    previewDialogVisible.value = true
  } 
  else if (fileExt === 'pdf') {
    // PDF文件使用iframe预览
    fileType.value = 'pdf'
    previewDialogVisible.value = true
  } 
  else if (['txt', 'log', 'md', 'json', 'xml', 'html', 'css', 'js'].includes(fileExt)) {
    // 文本文件需要获取内容后预览
    fileType.value = 'text'
    textContent.value = '' // 清空之前的内容
    previewDialogVisible.value = true
    
    try {
      // 这里应该是获取文本内容的API调用
      // 由于没有具体API，这里模拟一个请求
      const response = await fetch(previewUrl.value)
      if (response.ok) {
        textContent.value = await response.text()
      } else {
        message.error('无法加载文本内容')
      }
    } catch (error) {
      message.error('获取文本内容失败')
      console.error('获取文本内容失败:', error)
    }
  } 
  else if (['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'].includes(fileExt)) {
    // Office文档可以使用在线预览服务（如Office Online或自建服务）
    fileType.value = 'office'
    
    // 判断是否为外部URL
    if (filePath.startsWith('http://') || filePath.startsWith('https://')) {
      // 如果是外部URL，处理为Office预览服务可接受的格式
      officePreviewUrl.value = `${baseUrl}/api/preview/office?fileUrl=${encodeURIComponent(filePath)}`
    } else {
      // 如果是内部路径
      officePreviewUrl.value = `${baseUrl}/api/preview/office?filePath=${encodeURIComponent(filePath)}`
    }
    
    previewDialogVisible.value = true
  } 
  else {
    // 不支持预览的文件类型
    fileType.value = 'other'
    message.warning('该文件类型不支持在线预览，请下载后查看')
    downloadFile(file)
  }
}

/** 下载文件 */
const downloadFile = (file: any) => {
  // 构建文件下载URL
  const baseUrl = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL
  
  // 判断文件路径是否为完整URL
  let downloadUrl = file.filePath
  if (!(downloadUrl.startsWith('http://') || downloadUrl.startsWith('https://'))) {
    // 如果不是完整URL，拼接baseUrl
    downloadUrl = baseUrl + downloadUrl
  }

  // 创建隐藏的a标签进行下载
  const link = document.createElement('a')
  link.href = downloadUrl
  link.target = '_blank'
  link.download = file.fileName
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

/** 下载当前预览的文件 */
const downloadCurrentFile = () => {
  if (currentPreviewFile.value) {
    downloadFile(currentPreviewFile.value)
  }
}

/** 下载历史文件 */
const downloadHistoryFile = async (file: any) => {
  try {
    // 获取文件路径
    const filePath = file.filePath
    if (!filePath) {
      message.error('文件路径不存在')
      return
    }
    
    // 判断是否为外部URL
    // if (filePath.startsWith('http://') || filePath.startsWith('https://')) {
    //   // 直接使用外部URL下载
    //   window.open(filePath, '_blank')
    //   return
    // }
    
    // 直接使用filePath作为下载URL
    const downloadUrl = filePath
    
    // 显示加载中
    const loading = ElLoading.service({
      lock: true,
      text: '文件下载中...',
      background: 'rgba(0, 0, 0, 0.7)'
    })
    
    // 使用fetch API下载文件
    fetch(downloadUrl)
      .then(response => {
        if (!response.ok) {
          throw new Error('下载失败，服务器响应错误')
        }
        return response.blob()
      })
      .then(blob => {
        // 创建一个临时URL
        const url = window.URL.createObjectURL(blob)
        const a = document.createElement('a')
        a.href = url
        a.download = file.fileName || '未命名文件'
        document.body.appendChild(a)
        a.click()
        window.URL.revokeObjectURL(url)
        document.body.removeChild(a)
        message.success('下载成功')
      })
      .catch(error => {
        console.error('下载文件失败:', error)
        message.error('下载文件失败')
      })
      .finally(() => {
        // 关闭加载提示
        loading.close()
      })
  } catch (error) {
    console.error('下载历史文件失败', error)
    message.error('下载历史文件失败')
  }
}

/** 初始化 **/
onMounted(() => {
  getList()
})
</script>

<style scoped>
.file-preview-container {
  width: 100%;
  height: 70vh;
  overflow: auto;
}

.file-preview-frame {
  width: 100%;
  height: 100%;
  border: none;
}

.image-preview {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f5f7fa;
}

.preview-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.text-preview {
  width: 100%;
  height: 100%;
  padding: 20px;
  background-color: #f9f9f9;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  overflow: auto;
}

.text-content {
  white-space: pre-wrap;
  word-break: break-all;
  font-family: 'Courier New', monospace;
  margin: 0;
}

.loading-text {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  color: #909399;
}

.office-preview {
  width: 100%;
  height: 100%;
}

.filter-container {
  margin-bottom: 15px;
}

.filter-item {
  margin-right: 10px;
}

.w-200px {
  width: 200px;
}

.mr-10px {
  margin-right: 10px;
}
</style>